package org.javaforever.oville;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.javaforever.oville.operator.ClassicOps;
import org.javaforever.oville.operator.Code;
import org.javaforever.oville.operator.Decode;
import org.javaforever.oville.operator.Load;
import org.javaforever.oville.operator.Project;
import org.javaforever.oville.operator.QOps;
import org.javaforever.oville.operator.Write;

import test.orville.monkeytest.MonkeyTest;

public class Core {
	private Shell shell = new Shell(System.in,System.out);
	private Intercepter intercepter = new Intercepter();
	private List<Statement> statements = new ArrayList<Statement>();
	private Map<String,Var> vars = new TreeMap<String,Var>();
	private Map<String,VarMap> varMaps = new TreeMap<String,VarMap>();
	private List<Word> wordList = new ArrayList<Word>();
	private List<NarrowWord> narrowWordList = new ArrayList<NarrowWord>();
	private List<TextWord> textWordList = new ArrayList<TextWord>();
	private List<Words> wordsList = new ArrayList<Words>();
	private List<NarrowWords> narrowWordsList = new ArrayList<NarrowWords>();
	private List<TextWords> textWordsList = new ArrayList<TextWords>();
	private VarMap scriptResultMap = new VarMap();
	
  	public List<Word> getWordList() {
		return wordList;
	}
	public void setWordList(List<Word> wordList) {
		this.wordList = wordList;
	}
	public List<NarrowWord> getNarrowWordList() {
		return narrowWordList;
	}
	public void setNarrowWordList(List<NarrowWord> narrowWordList) {
		this.narrowWordList = narrowWordList;
	}
	public List<TextWord> getTextWordList() {
		return textWordList;
	}
	public void setTextWordList(List<TextWord> textWordList) {
		this.textWordList = textWordList;
	}
	public List<Words> getWordsList() {
		return wordsList;
	}
	public void setWordsList(List<Words> wordsList) {
		this.wordsList = wordsList;
	}
	public List<NarrowWords> getNarrowWordsList() {
		return narrowWordsList;
	}
	public void setNarrowWordsList(List<NarrowWords> narrowWordsList) {
		this.narrowWordsList = narrowWordsList;
	}
	public List<TextWords> getTextWordsList() {
		return textWordsList;
	}
	public void setTextWordsList(List<TextWords> textWordsList) {
		this.textWordsList = textWordsList;
	}
	public Shell getShell() {
		return shell;
	}
	public void setShell(Shell shell) {
		this.shell = shell;
	}
	public List<Statement> getStatements() {
		return statements;
	}
	public void setStatements(List<Statement> statements) {
		this.statements = statements;
	}
	
	public static void runScript(StatementList stats, Core core) throws Exception{
		for (Statement st:stats) {
			runCmd(st.getContent(),core);
		}
	}
	
	public static void main(String[] argv) {
		Core core = new Core();
		try {
			core.getShell().getOut().println("Orville quatum computer. Welcome!");
			while (true) {
				String input = core.getShell().input();
				runCmd(input,core);
			}
		} catch (ValidateException ve) {
			core.getShell().getOut().println(core.getShell().getPrompt() + ve.getMessage());
		} catch (Exception e) {
			core.getShell().getOut().println(core.getShell().getPrompt() + e.getMessage());
		}
	}
	
	public static void runCmd(String input,Core core) throws Exception{
		Action ac = core.intercepter.intercepte(new Statement(0, 0, input));
		if (ac != null && ac.getActionName().equals("setPrompt")) {
			core.getShell().setPrompt(ac.getParams().get("prompt"));
		}
		if (ac != null && ac.getActionName().equals("resetPrompt")) {
			core.getShell().setPrompt(core.getShell().getDefaultPrompt());
		}
		if (ac != null && ac.getActionName().equals("codeWord")) {
			String nword = ac.getParams().get("narrowWord");
			NarrowWord narrowWord = StringUtil.strToNarrowWord(nword, "narrowWord");
			Word w = Code.codeWord(narrowWord, "word");
			core.getShell().getOut().println("Word:" + w.toQuadStr());
		}
		if (ac != null && ac.getActionName().equals("code")) {
			String nwords = ac.getParams().get("narrowWords");
			NarrowWords narrowWords = StringUtil.strToNarrowWords(nwords, "narrowWords");
			Words ws = Code.code(narrowWords, "words");
			if (ac.getParams().get("varName") != null) {
				Var myVar = new Var();
				myVar.setVarType("words");
				myVar.setWords(ws);
				core.putVar(ac.getParams().get("varName"), myVar);
			}
			core.getShell().getOut().println("Words:" + ws.toQuadStr());
		}
		if (ac != null && ac.getActionName().equals("decode")) {
			String varName = ac.getParams().get("varName");
			Var myvar = core.getVars().get(varName);
			Words ws = myvar.getWords();

			NarrowWords nws = Decode.decode(ws, "narrowWords");
			core.getShell().getOut().println("NarrowWords:" + nws.toHexStr());
		}
		if (ac != null && ac.getActionName().equals("monkeyTest.monkeyNarrowWord")) {
			NarrowWord narrowWord = MonkeyTest.monkeyNarrowWord("narrowWord");
			core.getShell().getOut().println("NarrowWord:" + narrowWord.toHexStr());
		}
		if (ac != null && ac.getActionName().equals("monkeyTest.monkeyWord")) {
			Word word = MonkeyTest.monkeyWord("word");
			core.getShell().getOut().println("Word:" + word.toHexStr() + ":" + word.toQuadStr());
		}
		if (ac != null && ac.getActionName().equals("and")) {
			String nword1 = ac.getParams().get("narrowWord1");
			String nword2 = ac.getParams().get("narrowWord2");
			NarrowWord narrowWord1 = StringUtil.strToNarrowWord(nword1, "narrowWord1");
			NarrowWord narrowWord2 = StringUtil.strToNarrowWord(nword2, "narrowWord2");
			NarrowWord result = ClassicOps.and(narrowWord1, narrowWord2);
			core.getShell().getOut().println("NarrowWord and:" + result.toBinStr());
		}
		if (ac != null && ac.getActionName().equals("or")) {
			String nword1 = ac.getParams().get("narrowWord1");
			String nword2 = ac.getParams().get("narrowWord2");
			NarrowWord narrowWord1 = StringUtil.strToNarrowWord(nword1, "narrowWord1");
			NarrowWord narrowWord2 = StringUtil.strToNarrowWord(nword2, "narrowWord2");
			NarrowWord result = ClassicOps.or(narrowWord1, narrowWord2);
			core.getShell().getOut().println("NarrowWord or:" + result.toBinStr());
		}
		if (ac != null && ac.getActionName().equals("not")) {
			String nword1 = ac.getParams().get("narrowWord");
			NarrowWord narrowWord1 = StringUtil.strToNarrowWord(nword1, "narrowWord");
			System.out.println("JerryDebug:"+narrowWord1.toBinStr());
			NarrowWord result = ClassicOps.not(narrowWord1);
			core.getShell().getOut().println("NarrowWord not:" + result.toBinStr());
		}
		if (ac != null && ac.getActionName().equals("qAnd")) {
			String nword1 = ac.getParams().get("word1");
			String nword2 = ac.getParams().get("word2");
			Word word1 = StringUtil.strToWord(nword1, "word1");
			Word word2 = StringUtil.strToWord(nword2, "word2");
			List<Word> result = QOps.qAnd(word1, word2);
			for (Word w:result) {
				core.getShell().getOut().println("Word qAnd:" + w.toQuadStr());
			}
		}
		if (ac != null && ac.getActionName().equals("qOr")) {
			String nword1 = ac.getParams().get("word1");
			String nword2 = ac.getParams().get("word2");
			Word word1 = StringUtil.strToWord(nword1, "word1");
			Word word2 = StringUtil.strToWord(nword2, "word2");
			List<Word> result = QOps.qOr(word1, word2);
			for (Word w:result) {
				core.getShell().getOut().println("Word qOr:" + w.toQuadStr());
			}
		}
		if (ac != null && ac.getActionName().equals("qNot")) {
			String nword1 = ac.getParams().get("word");
			Word word1 = StringUtil.strToWord(nword1, "word");
			Word result = QOps.qNot(word1);
			core.getShell().getOut().println("Word qNot:" + result.toQuadStr());
		}
		if (ac != null && ac.getActionName().equals("let")) {
			String resultVar = ac.getParams().get("resultVar");
			String var1name = ac.getParams().get("var1");
			String var2name = ac.getParams().get("var2");
			String assignOps = ac.getParams().get("assignOps");
			String ops = ac.getParams().get("ops");
			NarrowWord narrowWord1;
			NarrowWord narrowWord2;
			Word word1;
			Word word2;
			if ("=".equals(assignOps)) {
			switch (ops) {
				case  "and" :
					if (var1name.startsWith("0x")||var1name.startsWith("0b")) {
						narrowWord1 = StringUtil.strToNarrowWord(var1name, "narrowWord1");
					} else {
						Var narrowWordVar1 = core.getVar(var1name);
						narrowWord1 = narrowWordVar1.getNarrowWord();
					}
					if (var2name.startsWith("0x")||var2name.startsWith("0b")) {
						narrowWord2 = StringUtil.strToNarrowWord(var2name, "narrowWord2");
					} else {
						Var narrowWordVar2 = core.getVar(var2name);
						narrowWord2 = narrowWordVar2.getNarrowWord();
					}
					NarrowWord result = ClassicOps.and(narrowWord1, narrowWord2);
					Var myResultVar = new Var();
					myResultVar.setNarrowWord(result);
					myResultVar.setVarName(resultVar);
					core.putVar(resultVar,myResultVar);
					core.getShell().getOut().println("let " + resultVar + " = " + result.toHexStr());
					break;
				case "or"	:
					if (var1name.startsWith("0x")||var1name.startsWith("0b")) {
						narrowWord1 = StringUtil.strToNarrowWord(var1name, "narrowWord1");
					} else {
						Var narrowWordVar1 = core.getVar(var1name);
						narrowWord1 = narrowWordVar1.getNarrowWord();
					}
					if (var2name.startsWith("0x")||var2name.startsWith("0b")) {
						narrowWord2 = StringUtil.strToNarrowWord(var2name, "narrowWord2");
					} else {
						Var narrowWordVar2 = core.getVar(var2name);
						narrowWord2 = narrowWordVar2.getNarrowWord();
					}
					result = ClassicOps.or(narrowWord1, narrowWord2);
					myResultVar = new Var();
					myResultVar.setNarrowWord(result);
					myResultVar.setVarName(resultVar);
					core.putVar(resultVar,myResultVar);
					core.getShell().getOut().println("let " + resultVar + " = " + result.toHexStr());
					break;
				case "xor"	:
					if (var1name.startsWith("0x")||var1name.startsWith("0b")) {
						narrowWord1 = StringUtil.strToNarrowWord(var1name, "narrowWord1");
					} else {
						Var narrowWordVar1 = core.getVar(var1name);
						narrowWord1 = narrowWordVar1.getNarrowWord();
					}
					if (var2name.startsWith("0x")||var2name.startsWith("0b")) {
						narrowWord2 = StringUtil.strToNarrowWord(var2name, "narrowWord2");
					} else {
						Var narrowWordVar2 = core.getVar(var2name);
						narrowWord2 = narrowWordVar2.getNarrowWord();
					}
					result = ClassicOps.xor(narrowWord1, narrowWord2);
					myResultVar = new Var();
					myResultVar.setNarrowWord(result);
					myResultVar.setVarName(resultVar);
					core.putVar(resultVar,myResultVar);
					core.getShell().getOut().println("let " + resultVar + " = " + result.toHexStr());
					break;
				case "add"	:
					if (var1name.startsWith("0x")||var1name.startsWith("0b")) {
						narrowWord1 = StringUtil.strToNarrowWord(var1name, "narrowWord1");
					} else {
						Var narrowWordVar1 = core.getVar(var1name);
						narrowWord1 = narrowWordVar1.getNarrowWord();
					}
					if (var2name.startsWith("0x")||var2name.startsWith("0b")) {
						narrowWord2 = StringUtil.strToNarrowWord(var2name, "narrowWord2");
					} else {
						Var narrowWordVar2 = core.getVar(var2name);
						narrowWord2 = narrowWordVar2.getNarrowWord();
					}
					result = ClassicOps.add(narrowWord1, narrowWord2);
					myResultVar = new Var();
					myResultVar.setNarrowWord(result);
					myResultVar.setVarName(resultVar);
					core.putVar(resultVar,myResultVar);
					core.getShell().getOut().println("let " + resultVar + " = " + result.toHexStr());
					break;
				case  "qAnd" :
					if (var1name.startsWith("0q")) {
						word1 = StringUtil.strToWord(var1name, "word1");
					} else {
						Var wordVar1 = core.getVar(var1name);
						word1 = wordVar1.getWord();
					}
					if (var2name.startsWith("0q")) {
						word2 = StringUtil.strToWord(var2name, "word2");
					} else {
						Var wordVar2 = core.getVar(var2name);
						word2 = wordVar2.getWord();
					}
					List<Word> qresult = QOps.qAnd(word1, word2);
					Words qresultwords = new Words();
					qresultwords.setWords(qresult);
					Var qsws = new Var();
					qsws.setWords(qresultwords);
					qsws.setVarName(resultVar);
					core.putVar(resultVar,qsws);
					core.getShell().getOut().println("let " + resultVar + " = " + qresultwords.toQuadStr());
					break;
				case "qOr"	:
					if (var1name.startsWith("0q")) {
						word1 = StringUtil.strToWord(var1name, "word1");
					} else {
						Var wordVar1 = core.getVar(var1name);
						word1 = wordVar1.getWord();
					}
					if (var2name.startsWith("0q")) {
						word2 = StringUtil.strToWord(var2name, "word2");
					} else {
						Var wordVar2 = core.getVar(var2name);
						word2 = wordVar2.getWord();
					}
					qresult = QOps.qOr(word1, word2);
					qresultwords = new Words();
					qresultwords.setWords(qresult);
					qsws = new Var();
					qsws.setWords(qresultwords);
					qsws.setVarName(resultVar);
					core.putVar(resultVar,qsws);
					core.getShell().getOut().println("let " + resultVar + " = " + qresultwords.toQuadStr());
					break;
				case "qXor"	:
					if (var1name.startsWith("0q")) {
						word1 = StringUtil.strToWord(var1name, "word1");
					} else {
						Var wordVar1 = core.getVar(var1name);
						word1 = wordVar1.getWord();
					}
					if (var2name.startsWith("0q")) {
						word2 = StringUtil.strToWord(var2name, "word2");
					} else {
						Var wordVar2 = core.getVar(var2name);
						word2 = wordVar2.getWord();
					}
					qresult = QOps.qXor(word1, word2);
					qresultwords = new Words();
					qresultwords.setWords(qresult);
					qsws = new Var();
					qsws.setWords(qresultwords);
					qsws.setVarName(resultVar);
					core.putVar(resultVar,qsws);
					core.getShell().getOut().println("let " + resultVar + " = " + qresultwords.toQuadStr());
					break;
				case "qZip"	:
					if (var1name.startsWith("0q")) {
						word1 = StringUtil.strToWord(var1name, "word1");
					} else {
						Var wordVar1 = core.getVar(var1name);
						word1 = wordVar1.getWord();
					}
					if (var2name.startsWith("0q")) {
						word2 = StringUtil.strToWord(var2name, "word2");
					} else {
						Var wordVar2 = core.getVar(var2name);
						word2 = wordVar2.getWord();
					}
					Word zipWord = QOps.qZip(word1, word2);
					qsws = new Var();
					qsws.setWord(zipWord);
					qsws.setVarName(resultVar);
					core.putVar(resultVar,qsws);
					core.getShell().getOut().println("let " + resultVar + " = " + zipWord.toQuadStr());
					break;
				}
			}
		}
		if (ac != null && ac.getActionName().equals("letSingle")) {
			String resultVar = ac.getParams().get("resultVar");
			String var1name = ac.getParams().get("var1");
			String assignOps = ac.getParams().get("assignOps");
			String ops = ac.getParams().get("ops");
			NarrowWord narrowWord1;
			NarrowWord narrowWord2;
			Word word1;
			Word word2;
			if ("=".equals(assignOps)) {
			switch (ops) {
				case  "not" :
					if (var1name.startsWith("0x")||var1name.startsWith("0b")) {
						narrowWord1 = StringUtil.strToNarrowWord(var1name, "narrowWord1");
					} else {
						Var narrowWordVar1 = core.getVar(var1name);
						narrowWord1 = narrowWordVar1.getNarrowWord();
					}
					NarrowWord result = ClassicOps.not(narrowWord1);
					Var myResultVar = new Var();
					myResultVar.setNarrowWord(result);
					myResultVar.setVarName(resultVar);
					core.putVar(resultVar,myResultVar);
					core.getShell().getOut().println("let " + resultVar + " = " + result.toHexStr());
					break;
				case  "qNot" :
					if (var1name.startsWith("0q")) {
						word1 = StringUtil.strToWord(var1name, "word1");
					} else {
						Var wordVar1 = core.getVar(var1name);
						word1 = wordVar1.getWord();
					}
					Word qresult = QOps.qNot(word1);
					Var qsws = new Var();
					qsws.setWord(qresult);
					qsws.setVarName(resultVar);
					core.putVar(resultVar,qsws);
					core.getShell().getOut().println("let " + resultVar + " = " + qresult.toQuadStr());
					break;
				case "qZipAll"	:
					Var wordVar1 = core.getVar(var1name);
					Words wordsList = wordVar1.getWords();
					Word zipWord = QOps.qZipAll(wordsList.getWords());
					qsws = new Var();
					qsws.setWord(zipWord);
					qsws.setVarName(resultVar);
					core.putVar(resultVar,qsws);
					core.getShell().getOut().println("let " + resultVar + " = " + zipWord.toQuadStr());
					break;
				case  "halfProject" :
					if (var1name.startsWith("0q")) {
						word1 = StringUtil.strToWord(var1name, "word1");
					} else {
						wordVar1 = core.getVar(var1name);
						word1 = wordVar1.getWord();
					}
					List<Word> qresults = Project.halfProject(word1);
					Words resultWs = new Words();
					resultWs.setVarName(resultVar);
					resultWs.setWords(qresults);
					Var resultWsVar = new Var();
					resultWsVar.setWords(resultWs);
					resultWsVar.setVarName(resultVar);
					core.putVar(resultVar,resultWsVar);
					core.getShell().getOut().println("let " + resultVar + " = " + resultWs.toQuadStr());
					break;	
				case  "project:0" :
					if (var1name.startsWith("0q")) {
						word1 = StringUtil.strToWord(var1name, "word1");
					} else {
						wordVar1 = core.getVar(var1name);
						word1 = wordVar1.getWord();
					}
					List<NarrowWord> nresults = Project.project(word1,'0');
					NarrowWords resultNws = new NarrowWords();
					resultNws.setVarName(resultVar);
					resultNws.setNarrowWords(nresults);
					resultWsVar = new Var();
					resultWsVar.setNarrowWords(resultNws);
					resultWsVar.setVarName(resultVar);
					core.putVar(resultVar,resultWsVar);
					core.getShell().getOut().println("let " + resultVar + " = " + resultNws.toHexStr());
					break;
				case  "project:1" :
					if (var1name.startsWith("0q")) {
						word1 = StringUtil.strToWord(var1name, "word1");
					} else {
						wordVar1 = core.getVar(var1name);
						word1 = wordVar1.getWord();
					}
					nresults = Project.project(word1,'1');
					resultNws = new NarrowWords();
					resultNws.setVarName(resultVar);
					resultNws.setNarrowWords(nresults);
					resultWsVar = new Var();
					resultWsVar.setNarrowWords(resultNws);
					resultWsVar.setVarName(resultVar);
					core.putVar(resultVar,resultWsVar);
					core.getShell().getOut().println("let " + resultVar + " = " + resultNws.toHexStr());
					break;
				case  "loadData" :
					TextWords tws = Load.loadData(var1name);
					Var retVar = new Var();
					retVar.setTextWords(tws);
					retVar.setVarName(resultVar);
					core.putVar(resultVar,retVar);
					core.getShell().getOut().println("let " + resultVar + " = " + retVar.toStr());
					break;	
				case  "loadStatements" :
					StatementList stls = Load.load(var1name);
					retVar = new Var();
					retVar.setStatementList(stls);
					retVar.setVarName(resultVar);
					core.putVar(resultVar,retVar);
					core.getShell().getOut().println("let " + resultVar + " = " + retVar.toStr());
					break;	
				case  "toTextWords" :
					if (!"StatementList".equals(core.getVar(var1name).getVarType())) throw new ValidateException("Not a statement list.");
					stls = core.getVar(var1name).getStatementList();
					tws = stls.toTextWords('*');
					tws.setVarName(resultVar);
					retVar = new Var();
					retVar.setTextWords(tws);
					retVar.setVarName(resultVar);
					core.putVar(resultVar,retVar);
					core.getShell().getOut().println("let " + resultVar + " = " + retVar.toStr());
					break;
				}
			}
		}
		if (ac != null && ac.getActionName().equals("letMonkey")) {
			String resultVar = ac.getParams().get("resultVar");
			String assignOps = ac.getParams().get("assignOps");
			String ops = ac.getParams().get("ops");
			NarrowWord narrowWord1;
			NarrowWord narrowWord2;
			Word word1;
			Word word2;
			if ("=".equals(assignOps)) {
			switch (ops) {
				case  "monkeyTest.monkeyNarrowWord" :
					NarrowWord result = MonkeyTest.monkeyNarrowWord(resultVar);
					Var myResultVar = new Var();
					myResultVar.setNarrowWord(result);
					myResultVar.setVarName(resultVar);
					core.putVar(resultVar,myResultVar);
					core.getShell().getOut().println("let " + resultVar + " = " + result.toHexStr());
					break;						
				case  "monkeyTest.monkeyWord" :
					Word qresult = MonkeyTest.monkeyWord(resultVar);
					Var qsws = new Var();
					qsws.setWord(qresult);
					qsws.setVarName(resultVar);
					core.putVar(resultVar,qsws);
					core.getShell().getOut().println("let " + resultVar + " = " + qresult.toQuadStr());
					break;						
				}
			}
		}
		if (ac != null && ac.getActionName().equals("letAssign")) {
			String resultVar = ac.getParams().get("resultVar");
			String var1name = ac.getParams().get("var1");
			String assignOps = ac.getParams().get("assignOps");
			String containsQuote = ac.getParams().get("containsQuote");
			Var var1 = core.getVar(var1name);
			if ("true".equals(containsQuote)) {
				Statement st = new Statement(0L,var1name.substring(1,var1name.length()-1));
				Var myVar = new Var();
				myVar.setStatement(st);
				myVar.setVarName(resultVar);
				core.putVar(resultVar, myVar);
				core.getShell().getOut().println("let " + resultVar + " = " + myVar.toStr());
			} else if (var1name.startsWith("0x")||var1name.startsWith("0b")) {
				NarrowWord narrowWord1 = StringUtil.strToNarrowWord(var1name, "narrowWord1");
				Var myVar = new Var();
				myVar.setNarrowWord(narrowWord1);
				myVar.setVarName(resultVar);
				core.putVar(resultVar, myVar);
				core.getShell().getOut().println("let " + resultVar + " = " + myVar.toStr());
			}else if (var1name.startsWith("0q")) {
				Word word1 = StringUtil.strToWord(var1name, "word1");
				Var myVar = new Var();
				myVar.setWord(word1);
				myVar.setVarName(resultVar);
				core.putVar(resultVar, myVar);
				core.getShell().getOut().println("let " + resultVar + " = " + myVar.toStr());
			}else if (var1 != null) {
				core.putVar(resultVar, var1);
				core.getShell().getOut().println("let " + resultVar + " = " + var1.toStr());
			}					
		}
		if (ac != null && ac.getActionName().equals("letToWords")) {
			String resultVar = ac.getParams().get("resultVar");
			String var1name = ac.getParams().get("var1");
			String assignOps = ac.getParams().get("assignOps");
			String pattern = ac.getParams().get("pattern");
			Var var1 = core.getVar(var1name);
			if (!"TextWords".equals(var1.getVarType())) throw new ValidateException("Wrong var type for letToWords operator.") ;
			TextWords tw1 = var1.getTextWords();
			Words words1 = tw1.toWords(pattern);
			Var myVar = new Var();
			myVar.setWords(words1);
			myVar.setVarName(resultVar);
			core.putVar(resultVar, myVar);
			core.getShell().getOut().println("let " + resultVar + " = " + myVar.toStr());			
		}
		if (ac != null && ac.getActionName().equals("letReplaceTextWords")) {
			String resultVar = ac.getParams().get("resultVar");
			String var1name = ac.getParams().get("var1");
			String assignOps = ac.getParams().get("assignOps");
			String pattern1 = ac.getParams().get("pattern1");
			String pattern2 = ac.getParams().get("pattern2");
			Var var1 = core.getVar(var1name);
			if (!"TextWords".equals(var1.getVarType())) throw new ValidateException("Wrong var type for letToWords operator.") ;
			TextWords tw1 = var1.getTextWords();
			TextWords tw2 = tw1.replace(pattern1, pattern2);
			Var myVar = new Var();
			myVar.setTextWords(tw2);
			myVar.setVarName(resultVar);
			core.putVar(resultVar, myVar);
			core.getShell().getOut().println("let " + resultVar + " = " + myVar.toStr());			
		}
		if (ac != null && ac.getActionName().equals("show")) {
			String var1name = ac.getParams().get("var1");
			if (core.getVar(var1name)!=null) {
				Var var1 = core.getVar(var1name);
				core.getShell().getOut().println("show " + var1.getVarName() + " = " + var1.toStr());
			} else if (core.getVarMap(var1name)!=null) {
				VarMap varMap1 = core.getVarMap(var1name);
				core.getShell().getOut().println("show " + varMap1.getVarName() + " = " + varMap1.toStr());
			} else if ("scriptResultMap".equals(var1name)) {
				VarMap varMap1 = core.getScriptResultMap();
				core.getShell().getOut().println("show " + varMap1.getVarName() + " = " + varMap1.toStr());
			}
		}
		if (ac != null && ac.getActionName().equals("write")) {
			String var1name = ac.getParams().get("var1");
			String filePath = ac.getParams().get("filePath");
			if (core.getVar(var1name)!=null) {
				Var var1 = core.getVar(var1name);
				Write.output(var1.toStatementList(), filePath);
				core.getShell().getOut().println("write " + var1.getVarName() + " = " + var1.toStr());
			}
		}
		if (ac != null && ac.getActionName().equals("run")) {
			String scriptPath = ac.getParams().get("scriptPath");
			StatementList stats = Load.load(scriptPath);
			core.getShell().getOut().println("run script " + scriptPath);
			runScript(stats,core);
		}
		if (ac != null && ac.getActionName().equals("return")) {
			String varMapName = ac.getParams().get("varMap");
			Var var1 = core.getVar(varMapName);	
			VarMap varMap;
			if (var1 != null) {
				varMap = new VarMap();
				varMap.putVar(varMapName, var1);
				core.setScriptResultMap(varMap);
			}else {
				varMap = core.getVarMap(varMapName);
				core.setScriptResultMap(varMap);
			}
			core.getShell().getOut().println("return " + varMap.getVarName());
		}
		if (ac != null && ac.getActionName().equals("comment")) {
		}
		if (ac != null && ac.getActionName().equals("quit")) {
			core.getShell().getOut().println("Byebye!");
			System.exit(0);
		}
	}
	
	public Intercepter getIntercepter() {
		return intercepter;
	}
	public void setIntercepter(Intercepter intercepter) {
		this.intercepter = intercepter;
	}
	public Map<String, Var> getVars() {
		return vars;
	}
	public Var getVar(String varName) {
		return this.vars.get(varName);
	}
	public void setVars(Map<String, Var> vars) {
		this.vars = vars;
	}
	public void putVar(String varName,Var var) {
		this.vars.put(varName, var);
	}
	public Map<String, VarMap> getVarMaps() {
		return varMaps;
	}
	public VarMap getVarMap(String varMapName) {
		return this.varMaps.get(varMapName);
	}
	public void setVarMaps(Map<String, VarMap> varMaps) {
		this.varMaps = varMaps;
	}
	public VarMap getScriptResultMap() {
		return scriptResultMap;
	}
	public void setScriptResultMap(VarMap scriptResultMap) {
		this.scriptResultMap = scriptResultMap;
	}
}
